package cn.xyf.mzmy.common.handle;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.xyf.mzmy.common.enums.GlobalErrorCodeConstants;
import cn.xyf.mzmy.common.exception.ServiceException;
import cn.xyf.mzmy.common.pojo.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.coyote.BadRequestException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 异常处理
 *
 * @author dhb
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理在没有登录请求的异常
     *
     * @param exception NotLoginException
     * @return 返回401的http状态码
     */
    @ResponseBody
    @ExceptionHandler(value = NotLoginException.class)
    public ResponseEntity<Result<String>> handle(NotLoginException exception) {
        log.debug("[NotLoginException]", exception);
        Result<String> r = new Result<>();
        r.setCode(HttpStatus.UNAUTHORIZED.value());
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(r);
    }


    /**
     * 处理参数错误的异常
     *
     * @param exception BadRequestException
     * @return 返回400状态码
     */
    @ResponseBody
    @ExceptionHandler(value = BadRequestException.class)
    public ResponseEntity<Result<String>> handle(BadRequestException exception) {
        Result<String> r = new Result<>();
        r.setMessage(exception.getMessage()).setData(null).setCode(HttpStatus.BAD_REQUEST.value());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(r);
    }


    /**
     * 处理业务异常
     *
     * @param exception BizException
     * @return 返回200的http状态码，body描述异常信息
     */
    @ResponseBody
    @ExceptionHandler(value = ServiceException.class)
    public Result<Object> handle(ServiceException exception) {
        log.error("[serviceExceptionHandler]", exception);
        return Result.fail(exception.getCode(), exception.getMessage());
    }


    /**
     * 处理角色无权操作异常
     *
     * @param exception ex
     * @return r
     */
    @ResponseBody
    @ExceptionHandler(value = NotRoleException.class)
    public Result<String> handle(NotRoleException exception) {
        log.debug("[NotRoleException]当前用户角色无权操作", exception);
        return Result.fail(GlobalErrorCodeConstants.FORBIDDEN);
    }

    /**
     * 处理参数错误异常
     *
     * @param exception ex
     * @return r
     */
    @ResponseBody
    @ExceptionHandler
    public Result<String> handle(MethodArgumentNotValidException exception) {
        ObjectError error = exception.getBindingResult().getAllErrors().get(0);
        String defaultMessage = error.getDefaultMessage();
        log.error("[MethodArgumentNotValidException]", exception);
        return Result.fail(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),defaultMessage);
    }

    /**
     * 处理系统异常，兜底处理所有的一切
     */
    @ExceptionHandler(value = Exception.class)
    public Result<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
        // 处理异常
        log.error("[defaultExceptionHandler]", ex);
        return Result.fail(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
    }

}
